package com.mk.manager;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.mk.config.CosClientConfig;
import com.mk.config.PictureConfig;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.exception.MultiObjectDeleteException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.model.ciModel.persistence.PicOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * COS 对象存储 工具类
 */
@Component
public class CosManager {

    @Resource
    private CosClientConfig cosClientConfig;

    @Resource
    private COSClient cosClient;

    @Autowired
    private PictureConfig pictureConfig;

    // ... 一些操作 COS 的方法

    /**
     * 上传对象
     *
     * @param key  唯一键
     * @param file 文件
     */
    public PutObjectResult putObject(String key, File file) {
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key,
                file);
        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 下载对象
     *
     * @param key 唯一键
     */
    public COSObject getObject(String key) {
        GetObjectRequest getObjectRequest = new GetObjectRequest(cosClientConfig.getBucket(), key);
        return cosClient.getObject(getObjectRequest);
    }

    /**
     * 上传图片
     *
     * @param key  唯一键
     * @param file 文件
     * @return 上传返回信息
     */
    public PutObjectResult putPictureObject(String key, File file) {
        /**
         * TODO 上传图片的原图，压缩图，缩略图 按需清理
         */
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosClientConfig.getBucket(), key, file);
        // 对图片进行处理（获取基本信息也被视作为一种图片的处理）
        PicOperations picOperations = new PicOperations();
        // 1 表示返回原图信息
        picOperations.setIsPicInfo(1);
        List<PicOperations.Rule> ruleList = new ArrayList<>();
        // 2.对图片压缩处理。格式转换，无损压缩
        if (pictureConfig.getFormat()) {
            PicOperations.Rule formatRule = new PicOperations.Rule();
            formatRule.setBucket(cosClientConfig.getBucket());
            String formatKey = String.format("%s_format.%s", FileUtil.mainName(key), "webp");
            formatRule.setFileId(formatKey);
            formatRule.setRule("imageMogr2/format/webp"); // 图片压缩（转成 webp 格式）
            ruleList.add(formatRule);
        }
        // 3. 缩略图处理，仅对 > 20 KB 的图片生成缩略图
        if (pictureConfig.getThumbnail()) {
            if (FileUtil.size(file) > (50 * 1024)) {
                PicOperations.Rule thumbnailRule = new PicOperations.Rule();
                thumbnailRule.setBucket(cosClientConfig.getBucket());
                String thumbnailKey = String.format("%s_thumbnail.%s", FileUtil.mainName(key), FileUtil.getSuffix(key));
                thumbnailRule.setFileId(thumbnailKey);
                // 缩放规则 /thumbnail/<Width>x<Height>>（如果大于原图宽高，则不处理）
                thumbnailRule.setRule(String.format("imageMogr2/thumbnail/%sx%s>", 256, 256));
                ruleList.add(thumbnailRule);
            }
        }
        // 构造处理参数
        if (ObjUtil.isNotEmpty(ruleList))
            picOperations.setRules(ruleList); // 设置图片处理规则
        putObjectRequest.setPicOperations(picOperations); // 设置上传对象为图片信息

        return cosClient.putObject(putObjectRequest);
    }

    /**
     * 根据key删除存储对象 批量删除
     *
     * @param keys
     */
    public void deleteObject(String... keys) {

        Set<String> keySet = new HashSet<>(Arrays.asList(keys)); // 去重
        List<DeleteObjectsRequest.KeyVersion> keyVersionList = keySet.stream()
                .filter(StrUtil::isNotBlank)  // 过滤掉空字符串和 null 值
                .map(DeleteObjectsRequest.KeyVersion::new)  // 转换为 KeyVersion 对象
                .collect(Collectors.toList());  // 收集到列表中

        // 设置删除请求
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(cosClientConfig.getBucket());
        deleteObjectsRequest.setKeys(keyVersionList);
        try {
            cosClient.deleteObjects(deleteObjectsRequest);
        } catch (MultiObjectDeleteException mde) {
            // 如果部分删除成功部分失败, 返回 MultiObjectDeleteException
            mde.printStackTrace();
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        }
    }


}
